﻿using Framework.EncryptionDecryptionService.Achieve;
using Framework.EncryptionDecryptionService.Attributes;
using Framework.EncryptionDecryptionService.Enums;
using Framework.EncryptionDecryptionService.Inteface;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using System.Windows.Markup;

namespace Framework.EncryptionDecryptionService
{
    /// <summary>
    /// 注入加解密服务
    /// </summary>
    public static class InjectEncryptionDecryptionService
    {
        /// <summary>
        /// 注入加解密服务
        /// </summary>
        /// <param name="service"></param>
        public static void AddEncryptionDecryptionService(this IServiceCollection service)
        {
            //自动注入秘钥服务
            AutomaticInjection<ISecretKeyService>(service);
            //自动注入解密键控服务
            AutomaticDecryptionKeyedInjection(service);
            //自动注入加密键控服务
            AutomaticEncryptionKeyedInjection(service);

            //service.AddKeyedSingleton(typeof(DecryptionServiceRsa), EncryptionAlgorithm.RSA, typeof(DecryptionServiceRsa));
            ////注入 RSA-键控服务-解密-单例模式
            //service.AddKeyedSingleton<IDecryptionService, DecryptionServiceRsa>(EncryptionAlgorithm.RSA);
            ////注入 RSA-键控服务-加密-单例模式
            //service.AddKeyedSingleton<IEncryptionService, EncryptionServiceRsa>(EncryptionAlgorithm.RSA);

            ////注入 AES-键控服务-解密-单例模式
            //service.AddKeyedSingleton<IDecryptionService, DecryptionServiceAes>(EncryptionAlgorithm.AES);
            ////注入 AES-键控服务-加密-单例模式
            //service.AddKeyedSingleton<IEncryptionService, EncryptionServiceAes>(EncryptionAlgorithm.AES);

            //注入 加解密服务
            service.AddSingleton<IEncryptionDecryptionService, Achieve.EncryptionDecryptionService>();
        }

        /// <summary>
        /// 获取运行的所有程序集
        /// </summary>
        private static readonly Lazy<Assembly[]> Assemblies = new Lazy<Assembly[]>(() => AppDomain.CurrentDomain.GetAssemblies());

        /// <summary>
        /// 获取接口的所有实现
        /// </summary>
        /// <typeparam name="InteFace"></typeparam>
        /// <returns></returns>
        public static IEnumerable<Type> GetAllImplementations<InteFace>()
        {
            // 获取当前应用程序域中所有已加载的程序集
            var assemblies = Assemblies.Value;

            var implementations = new List<Type>();

            foreach (var assembly in assemblies)
            {
                try
                {
                    // 获取程序集中所有公开的、非抽象的类型
                    var types = assembly.GetExportedTypes()
                        .Where(t => t.IsClass && !t.IsAbstract);

                    foreach (var type in types)
                    {
                        // 检查是否实现了ISecretKeyService接口
                        if (typeof(InteFace).IsAssignableFrom(type))
                        {
                            implementations.Add(type);
                        }
                    }
                }
                catch (ReflectionTypeLoadException)
                {
                    // 忽略无法加载类型的程序集
                    continue;
                }
            }

            return implementations;
        }

        /// <summary>
        /// 自动注入秘钥服务
        /// </summary>
        /// <typeparam name="InteFace">接口</typeparam>
        /// <param name="service"></param>
        public static void AutomaticInjection<InteFace>(IServiceCollection service, ServiceLifetime lifetime = ServiceLifetime.Singleton)
        {
            var data = GetAllImplementations<InteFace>();
            if (data.Any())
            {
                data.ToList().ForEach(x =>
                {
                    switch (lifetime)
                    {
                        case ServiceLifetime.Singleton:
                            //注入 单例 秘钥服务
                            service.AddSingleton(x);
                            //注入 单例 秘钥服务
                            service.AddSingleton(typeof(InteFace), x);
                            break;
                        case ServiceLifetime.Scoped:
                            //注入 请求作用域 秘钥服务
                            service.AddScoped(x);
                            //注入 请求作用域 秘钥服务
                            service.AddScoped(typeof(InteFace), x);
                            break;
                        case ServiceLifetime.Transient:
                            //注入 瞬时 秘钥服务
                            service.AddTransient(x);
                            //注入 瞬时 秘钥服务
                            service.AddTransient(typeof(InteFace), x);
                            break;
                    }
                });
            }
        }

        /// <summary>
        /// 自动注入 解密-键控 服务
        /// </summary>
        /// <param name="service"></param>
        public static void AutomaticDecryptionKeyedInjection(IServiceCollection service, ServiceLifetime lifetime = ServiceLifetime.Singleton)
        {
            var data = GetAllImplementations<IDecryptionService>();
            if (data.Any())
            {
                data.ToList().ForEach(x =>
                {
                    var attr= x.GetCustomAttribute<EncryptionAttribute>();
                    var encryptionType = attr?.EncryptionType;
                    if (encryptionType != null)
                    {
                        switch (lifetime)
                        {
                            case ServiceLifetime.Singleton:
                                //注入 单例 解密服务
                                service.AddKeyedSingleton(typeof(IDecryptionService), encryptionType, x);
                                break;
                            case ServiceLifetime.Scoped:
                                //注入 请求作用域 解密服务
                                service.AddKeyedScoped(typeof(IDecryptionService), encryptionType, x);
                                break;
                            case ServiceLifetime.Transient:
                                //注入 瞬时 解密服务
                                service.AddKeyedTransient(typeof(IDecryptionService), encryptionType, x);
                                break;
                        }
                    }
                });
            }
        }
        /// <summary>
        /// 自动注入 加密-键控 服务
        /// </summary>
        /// <param name="service"></param>
        public static void AutomaticEncryptionKeyedInjection(IServiceCollection service, ServiceLifetime lifetime = ServiceLifetime.Singleton)
        {
            var data = GetAllImplementations<IEncryptionService>();
            if (data.Any())
            {
                data.ToList().ForEach(x =>
                {
                    var attr = x.GetCustomAttribute<EncryptionAttribute>();
                    var encryptionType = attr?.EncryptionType;
                    if (encryptionType != null)
                    {
                        switch (lifetime)
                        {
                            case ServiceLifetime.Singleton:
                                //注入 单例 加密服务
                                service.AddKeyedSingleton(typeof(IEncryptionService), encryptionType, x);
                                break;
                            case ServiceLifetime.Scoped:
                                //注入 请求作用域 加密服务
                                service.AddKeyedScoped(typeof(IEncryptionService), encryptionType, x);
                                break;
                            case ServiceLifetime.Transient:
                                //注入 瞬时 加密服务
                                service.AddKeyedTransient(typeof(IEncryptionService), encryptionType, x);
                                break;
                        }
                    }
                });
            }
        }
    }
}
